home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / ixemlsrc.lha / ixemul / library / socket.c < prev    next >
C/C++ Source or Header  |  1995-12-23  |  29KB  |  1,302 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  socket.c,v 1.1.1.1 1994/04/04 04:29:41 amiga Exp
  20.  *
  21.  *  socket.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:29:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  * Revision 1.2  1993/11/05  22:02:33  mwild
  26.  * inet.library code, plus NOT YET WORKING code for "own" sockets
  27.  *
  28.  */
  29.  
  30. #define KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. #include <sys/socket.h>
  35. #include <sys/socketvar.h>
  36. #include <sys/ioctl.h>
  37. #include <net/if.h>
  38. #include <net/route.h>
  39. #include <netinet/in.h>
  40. #include "select.h"
  41. #include <machine/param.h>
  42.  
  43. static struct file *getsock (int fdes);
  44. static int soo_read  (struct file *fp, char *buf, int len);
  45. static int soo_write (struct file *fp, char *buf, int len);
  46. static int soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  47. static int soo_select(struct file *fp, int select_cmd, int io_mode);
  48. static int soo_close (struct file *fp);
  49.  
  50. /* inet.library is just as weird as ixemul.library... it takes all parameters
  51.    in parameter structures, addressed by d1 (a datareg taking an address..). */
  52. #include "inet.h"
  53.  
  54. int
  55. socket (int domain, int type, int protocol)
  56. {
  57.   struct a {
  58.           short   domain;
  59.           short   type;
  60.           short   protocol;
  61.           char    sigurg;
  62.           char    sigio;
  63.           short   err;
  64.           struct socket *so;
  65.   } uap;
  66.   struct file *fp;
  67.   struct user *p = &u;
  68.   int fd, err, ostat, omask;
  69.  
  70.   if (domain == AF_INET && ! p->u_InetBase)
  71.     {
  72.       errno = ENOSYS;
  73.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  74.       return -1;
  75.     }
  76.  
  77.   ostat = p->p_stat;
  78.   p->p_stat = SWAIT;
  79.   omask = syscall (SYS_sigsetmask, ~0);
  80.   do
  81.     {
  82.       if ((err = falloc (&fp, &fd)))
  83.         break;
  84.  
  85. #if defined (U_SOCKETS)
  86.       if (domain == AF_INET)
  87.     {
  88. #endif
  89.            uap.domain   = domain;
  90.            uap.type     = type;
  91.            uap.protocol = protocol;
  92.            uap.sigurg   = u.u_sigurg;
  93.            uap.sigio    = u.u_sigio;
  94.            uap.err      = 0;
  95.       
  96.        IN_socket(p->u_InetBase, &uap);
  97.            fp->f_so = uap.so;
  98.            err = uap.err;
  99. #if defined (U_SOCKETS)
  100.     }
  101.       else
  102.     {
  103.        struct socket *so;
  104.  
  105.        err = socreate (domain, &so, type, protocol);
  106.     }
  107. #endif
  108.       if (err)
  109.     {
  110.       /* free the allocated fd */
  111.       p->u_ofile[fd] = 0;
  112.       fp->f_count = 0;
  113.           break;
  114.     }
  115.     
  116.       fp->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  117.       fp->f_stb.st_size = 128;    /* sizeof mbuf. */
  118.       fp->f_stb.st_blksize = 128;
  119.  
  120.       fp->f_flags  = FREAD|FWRITE;
  121.       fp->f_type   = domain == AF_INET ? DTYPE_SOCKET : DTYPE_USOCKET;
  122.       fp->f_read   = soo_read;
  123.       fp->f_write  = soo_write;
  124.       fp->f_ioctl  = soo_ioctl;
  125.       fp->f_close  = soo_close;
  126.       fp->f_select = soo_select;
  127.     }
  128.   while (0);
  129.   syscall (SYS_sigsetmask, omask);
  130.   if (CURSIG (p))
  131.     SetSignal (0, SIGBREAKF_CTRL_C);
  132.   p->p_stat = ostat;
  133.   if (err == EINTR)
  134.     setrun (FindTask (0));
  135.  
  136.   errno = err;
  137.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  138.   return err ? -1 : fd;
  139. }
  140.  
  141.  
  142. int
  143. bind (int s, caddr_t name, int namelen)
  144. {
  145.   struct a {
  146.           struct socket    *so;
  147.           caddr_t    name;
  148.           short        namelen;
  149.           short        err;
  150.   } uap;
  151.   register struct file *fp = getsock (s);
  152.   struct user *p = &u;
  153.   int ostat, error;
  154.  
  155.   if (! fp)
  156.     return -1;
  157.  
  158.   ostat = p->p_stat;
  159.   p->p_stat = SWAIT;
  160. #if defined (U_SOCKETS)
  161.   if (fp->f_type == DTYPE_SOCKET)
  162.     {
  163. #endif
  164.       uap.so      = fp->f_so;
  165.       uap.name    = name;
  166.       uap.namelen = namelen;
  167.       uap.err     = 0;
  168.   
  169.       IN_bind(p->u_InetBase, &uap);
  170.       error = uap.err;
  171. #if defined (U_SOCKETS)
  172.     }
  173.   else
  174.     {
  175.       struct mbuf *nam;
  176.       error = sockargs (&nam, name, namelen, MT_SONAME);
  177.       if (! error)
  178.     {
  179.           error = sobind (fp->f_so, nam);
  180.           m_freem (nam);
  181.         }
  182.     }
  183. #endif
  184.  
  185.   if (CURSIG (p))
  186.     SetSignal (0, SIGBREAKF_CTRL_C);
  187.   p->p_stat = ostat;
  188.   if (error == EINTR)
  189.     setrun (FindTask (0));
  190.   
  191.   errno = error;
  192.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  193.   return error ? -1 : 0;
  194. }
  195.  
  196. int
  197. listen (int s, int backlog)
  198. {
  199.   struct a {
  200.           struct socket *so;
  201.           short         backlog;
  202.           short         err;
  203.   } uap;
  204.   register struct file *fp = getsock (s);
  205.   struct user *p = &u;
  206.   int ostat, error;
  207.  
  208.   if (! fp)
  209.     return -1;
  210.  
  211.   ostat = p->p_stat;
  212.   p->p_stat = SWAIT;
  213.  
  214. #if defined (U_SOCKETS)
  215.   if (fp->f_type == DTYPE_SOCKET)
  216.     {
  217. #endif
  218.       uap.so      = fp->f_so;
  219.       uap.backlog = backlog;
  220.       uap.err     = 0;
  221.       IN_listen(p->u_InetBase, &uap);
  222.       error = uap.err;
  223. #if defined (U_SOCKETS)
  224.     }
  225.   else
  226.     {
  227.       error = solisten (fp->f_so, backlog);
  228.     }
  229. #endif
  230.   if (CURSIG (p))
  231.     SetSignal (0, SIGBREAKF_CTRL_C);
  232.   p->p_stat = ostat;
  233.   if (error == EINTR)
  234.     setrun (FindTask (0));
  235.  
  236.   errno = error;
  237.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  238.   return error ? -1 : 0;
  239. }
  240.  
  241. int
  242. accept (int s, caddr_t name, int *namelen)
  243. {
  244.   struct a {
  245.           struct socket *so;
  246.           caddr_t name;
  247.           short   namelen;
  248.           short   err;
  249.           struct socket *so2;
  250.   } uap;
  251.   struct file *fp = getsock (s), *fp2;
  252.   struct user *p = &u;
  253.   int err, fd2, ostat;
  254.   
  255.   if (! fp)
  256.     return -1;
  257.     
  258.   ostat = p->p_stat;
  259.   p->p_stat = SWAIT;
  260.   do
  261.     {
  262.       /* first try to get a new descriptor. If that fails, don't even
  263.          bother to call the library */
  264.       if ((err = falloc (&fp2, &fd2)))
  265.         break;
  266.       
  267. #if defined (U_SOCKETS)
  268.       if (fp->f_type == DTYPE_SOCKET)
  269.         {
  270. #endif
  271.           uap.so      = fp->f_so;
  272.           uap.name    = name;
  273.           uap.namelen = namelen ? *namelen : 0;
  274.           uap.so2      = 0;
  275.           uap.err     = 0;
  276.           IN_accept(p->u_InetBase, &uap);
  277.           if (! uap.so2 && !uap.err)
  278.             uap.err = EINTR;    /* XXX */
  279.       err = uap.err;
  280.           if (namelen)
  281.             *namelen = uap.namelen;
  282.  
  283.           fp2->f_so = uap.so2;
  284. #if defined (U_SOCKETS)
  285.     }
  286.       else
  287.         {
  288.       struct socket *so = fp->f_so;
  289.  
  290.           if ((so->so_options & SO_ACCEPTCONN) == 0) 
  291.             err = EINVAL;
  292.           else if ((so->so_state & SS_NBIO) && so->so_qlen == 0)
  293.         err = EWOULDBLOCK;
  294.       else
  295.         {
  296.           while (so->so_qlen == 0 && so->so_error == 0) 
  297.             {
  298.           if (so->so_state & SS_CANTRCVMORE) 
  299.             {
  300.               so->so_error = ECONNABORTED;
  301.               break;
  302.             }
  303.           if (err = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  304.               netcon, 0))
  305.             {
  306.               so->so_error = err;
  307.               break;
  308.             }
  309.             }
  310.           if (so->so_error)
  311.             {
  312.               err = so->so_error;
  313.               so->so_error = 0;
  314.         }
  315.           else
  316.             {
  317.               struct socket *aso = so->so_q;
  318.               struct mbuf *nam;
  319.               if (soqremque (aso, 1) == 0)
  320.                 panic ("accept");
  321.               
  322.               fp2->f_so = aso;
  323.               nam = m_get (M_WAIT, MT_SONAME);
  324.               (void) soaccept (aso, nam);
  325.               if (name && namelen)
  326.                 {
  327.                   if (*namelen > nam->m_len)
  328.                     *namelen = nam->m_len;
  329.                   bcopy (mtod (nam, caddr_t), name, *namelen);
  330.                 }
  331.               m_freem (nam);
  332.             }
  333.         }
  334.         }
  335. #endif
  336.  
  337.       if (err)
  338.         {
  339.           /* free the second file */
  340.           u.u_ofile[fd2] = 0;
  341.           fp2->f_count = 0;
  342.           break;
  343.         }
  344.  
  345.     
  346.       fp2->f_stb.st_mode = 0666 | S_IFSOCK; /* not always, but.. */
  347.       fp2->f_stb.st_size = 128;    /* sizeof mbuf.. */
  348.       fp2->f_stb.st_blksize = 128;
  349.  
  350.       fp2->f_flags  = FREAD|FWRITE;
  351.       fp2->f_type   = DTYPE_SOCKET;
  352.       fp2->f_read   = soo_read;
  353.       fp2->f_write  = soo_write;
  354.       fp2->f_ioctl  = soo_ioctl;
  355.       fp2->f_close  = soo_close;
  356.       fp2->f_select = soo_select;
  357.     }
  358.   while (0);
  359.   if (CURSIG (p))
  360.     SetSignal (0, SIGBREAKF_CTRL_C);
  361.   p->p_stat = ostat;
  362.   if (err == EINTR)
  363.     setrun (FindTask (0));
  364.  
  365.   errno = err;
  366.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  367.   return err ? -1 : fd2;
  368. }
  369.  
  370.  
  371. int
  372. connect (int s, caddr_t name, int namelen)
  373. {
  374.   struct a {
  375.           struct socket *so;
  376.           caddr_t name;
  377.           short   namelen;
  378.           short   err;
  379.   } uap;
  380.   register struct file *fp = getsock (s);
  381.   struct user *p = &u;
  382.   int ostat, error;
  383.  
  384.   if (! fp)
  385.     return -1;
  386.  
  387.   ostat = p->p_stat;
  388.   p->p_stat = SWAIT;
  389.  
  390. #if defined (U_SOCKETS)
  391.   if (fp->f_type == DTYPE_SOCKET)
  392.     {
  393. #endif
  394.       uap.so      = fp->f_so;
  395.       uap.name    = name;
  396.       uap.namelen = namelen;
  397.       uap.err     = 0;
  398.       IN_connect(p->u_InetBase, &uap);
  399.       error = uap.err;
  400. #if defined (U_SOCKETS)
  401.     }
  402.   else
  403.     {
  404.       struct socket *so = fp->f_so;
  405.       struct mbuf *nam;
  406.  
  407.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
  408.         {
  409.       error = EALREADY;
  410.       break;
  411.     }
  412.       if (error = sockargs(&nam, name, namelen, MT_SONAME))
  413.     break;
  414.  
  415.       error = soconnect(so, nam);
  416.       if (error)
  417.     goto bad;
  418.       if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) 
  419.     {
  420.       m_freem(nam);
  421.       error = EINPROGRESS;
  422.     }
  423.  
  424.       Forbid ();
  425.       while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
  426.     if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
  427.                    netcon, 0))
  428.       break;
  429.       if (error == 0) 
  430.     {
  431.       error = so->so_error;
  432.       so->so_error = 0;
  433.     }
  434.       Permit ();
  435. bad:
  436.       so->so_state &= ~SS_ISCONNECTING;
  437.       m_freem(nam);
  438.       if (error == ERESTART)
  439.     error = EINTR;
  440.     }
  441. #endif
  442.  
  443.   if (CURSIG (p))
  444.     SetSignal (0, SIGBREAKF_CTRL_C);
  445.   p->p_stat = ostat;
  446.   if (error == EINTR)
  447.     setrun (FindTask (0));
  448.  
  449.   errno = error;
  450.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  451.   return error ? -1 : 0;
  452. }
  453.  
  454. #if 0
  455. /* This function is not available with Commodore sockets. */
  456.  
  457. int
  458. socketpair (int domain, int type, int protocol, int sv[2])
  459. {
  460.   register struct file *fp1, *fp2;
  461.   struct socket *so1, *so2;
  462.   struct user *p = &u;
  463.   int ostat, error;
  464.  
  465.   /* minimal test.. */
  466.   if (!sv[0] || !sv[1])
  467.     {
  468.       errno = EFAULT;
  469.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  470.       return -1;
  471.     }
  472.  
  473.   /* no go with Commo-sockets */
  474.   if (domain == AF_INET)
  475.     {
  476.       errno = EPFNOSUPPORT;
  477.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  478.       return -1;
  479.     }
  480.  
  481.   ostat = p->p_stat;
  482.   p->p_stat = SWAIT;
  483.   do
  484.     {
  485.       /* first try to allocate two descriptors */
  486.       if (error = falloc (&fp1, &sv[0]))
  487.         break;
  488.         
  489.       if (error = falloc (&fp2, &sv[1]))
  490.         {
  491. free_first:
  492.       /* free first descriptor */
  493.           u.u_ofile[sv[0]] = 0;
  494.           fp1->f_count = 0;
  495.           break;
  496.         }
  497.  
  498.       if (error = socreate(domain, &so1, type, protocol))
  499.         {
  500. free_second:
  501.           u.u_ofile[sv[1]] = 0;
  502.           fp2->f_count = 0;
  503.           goto free_first;
  504.         }
  505.  
  506.       if (error = socreate(domain, &so2, type, protocol))
  507.         {
  508. close_so1:
  509.       soclose (so1);
  510.           goto free_second;
  511.         }
  512.       
  513.       if (error = soconnect2(so1, so2))
  514.         {
  515. close_so2:
  516.       soclose (so2);
  517.       goto close_so1;
  518.     }
  519.        
  520.       if (type == SOCK_DGRAM) 
  521.     {
  522.       /*
  523.        * Datagram socket connection is asymmetric.
  524.        */
  525.       if (error = soconnect2(so2, so1))
  526.         goto close_so2;
  527.     }
  528.     }
  529.   while (0);
  530.   p->p_stat = ostat;
  531.  
  532.   if (error == EINTR)
  533.     setrun (FindTask (0));
  534.   
  535.   errno = error;
  536.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  537.   return error ? -1 : 0;
  538. }
  539. #endif
  540.  
  541.  
  542. int
  543. sendto (int s, caddr_t buf, int len, int flags, caddr_t to, int tolen)
  544. {
  545.   struct a {
  546.           struct socket *so;
  547.           caddr_t buf;
  548.           int     len;
  549.           short   flags;
  550.           caddr_t to;
  551.           short   tolen;
  552.           short   err;
  553.           int     rc;
  554.   } uap;
  555.   register struct file *fp = getsock (s);
  556.   struct user *p = &u;
  557.   int ostat;
  558.  
  559.   if (! fp)
  560.     return -1;
  561.  
  562.   ostat = p->p_stat;
  563.   p->p_stat = SWAIT;
  564.   uap.so    = fp->f_so;
  565.   uap.buf   = buf;
  566.   uap.len   = len;
  567.   uap.flags = flags;
  568.   uap.to    = to;
  569.   uap.tolen = tolen;
  570.   uap.err   = 0;
  571.   IN_sendto(p->u_InetBase, &uap);
  572.   if (CURSIG (p))
  573.     SetSignal (0, SIGBREAKF_CTRL_C);
  574.   p->p_stat = ostat;
  575.  
  576.   /* the library doesn't send this to us of course ;-) */
  577.   if (uap.err == EPIPE)
  578.     _psignal (FindTask (0), SIGPIPE);
  579.   if (uap.err == EINTR)
  580.     setrun (FindTask (0));
  581.   
  582.   errno = uap.err;
  583.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  584.   return uap.err ? -1 : uap.rc;
  585. }
  586.  
  587.  
  588. int
  589. send (int s, caddr_t buf, int len, int flags)
  590. {
  591.   struct a {
  592.           struct socket *so;
  593.           caddr_t buf;
  594.           int     len;
  595.           short   flags;
  596.           short   err;
  597.           int     rc;
  598.   } uap;
  599.   register struct file *fp = getsock (s);
  600.   struct user *p = &u;
  601.   int ostat;
  602.  
  603.   if (! fp)
  604.     return -1;
  605.  
  606.   ostat = p->p_stat;
  607.   p->p_stat = SWAIT;
  608.   uap.so    = fp->f_so;
  609.   uap.buf   = buf;
  610.   uap.len   = len;
  611.   uap.flags = flags;
  612.   uap.err   = 0;
  613.   IN_send (p->u_InetBase, &uap);
  614.   if (CURSIG (p))
  615.     SetSignal (0, SIGBREAKF_CTRL_C);
  616.   p->p_stat = ostat;
  617.   
  618.   /* the library doesn't send this to us of course ;-) */
  619.   if (uap.err == EPIPE)
  620.     _psignal (FindTask (0), SIGPIPE);
  621.   if (uap.err == EINTR)
  622.     setrun (FindTask (0));
  623.   
  624.   errno = uap.err;
  625.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  626.   return uap.err ? -1 : uap.rc;
  627. }
  628.  
  629.  
  630. int
  631. sendmsg (int s, caddr_t msg, int flags)
  632. {
  633.   struct a {
  634.           struct socket *so;
  635.           caddr_t msg;
  636.           short   flags;
  637.           short   err;
  638.           int     rc;
  639.   } uap;
  640.   register struct file *fp = getsock (s);
  641.   struct user *p = &u;
  642.   int ostat;
  643.  
  644.   if (! fp)
  645.     return -1;
  646.  
  647.   ostat = p->p_stat;
  648.   p->p_stat = SWAIT;
  649.   uap.so    = fp->f_so;
  650.   uap.msg   = msg;
  651.   uap.flags = flags;
  652.   uap.err   = 0;
  653.   IN_sendmsg (p->u_InetBase, &uap);
  654.   if (CURSIG (p))
  655.     SetSignal (0, SIGBREAKF_CTRL_C);
  656.   p->p_stat = ostat;
  657.   
  658.   /* the library doesn't send this to us of course ;-) */
  659.   if (uap.err == EPIPE)
  660.     _psignal (FindTask (0), SIGPIPE);
  661.   if (uap.err == EINTR)
  662.     setrun (FindTask (0));
  663.   
  664.   errno = uap.err;
  665.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  666.   return uap.err ? -1 : uap.rc;
  667. }
  668.  
  669.  
  670. int
  671. recvfrom (int s, caddr_t buf, int len, int flags, caddr_t from, int *fromlen)
  672. {
  673.   struct a {
  674.           struct socket *so;
  675.           caddr_t buf;
  676.           int     len;
  677.           short   flags;
  678.           caddr_t from;
  679.           short   fromlen;
  680.           short   err;
  681.           int     rc;
  682.   } uap;
  683.   register struct file *fp = getsock (s);
  684.   struct user *p = &u;
  685.   int ostat;
  686.  
  687.   if (! fp)
  688.     return -1;
  689.  
  690.   ostat = p->p_stat;
  691.   p->p_stat = SWAIT;
  692.   uap.so      = fp->f_so;
  693.   uap.buf     = buf;
  694.   uap.len     = len;
  695.   uap.flags   = flags;
  696.   uap.from    = from;
  697.   uap.fromlen = fromlen ? *fromlen : 0;
  698.   uap.err     = 0;
  699.   IN_recvfrom (p->u_InetBase, &uap);
  700.   if (CURSIG (p))
  701.     SetSignal (0, SIGBREAKF_CTRL_C);
  702.   p->p_stat = ostat;
  703.   if (uap.err == EINTR)
  704.     setrun (FindTask (0));
  705.   if (fromlen)
  706.     *fromlen = uap.fromlen;
  707.   
  708.   errno = uap.err;
  709.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  710.   return uap.err ? -1 : uap.rc;
  711. }
  712.  
  713.  
  714. int
  715. recv (int s, caddr_t buf, int len, int flags)
  716. {
  717.   struct a {
  718.           struct socket *so;
  719.           caddr_t buf;
  720.           int     len;
  721.           short   flags;
  722.           short   err;
  723.           int     rc;
  724.   } uap;
  725.   register struct file *fp = getsock (s);
  726.   struct user *p = &u;
  727.   int ostat;
  728.  
  729.   if (! fp)
  730.     return -1;
  731.  
  732.   ostat = p->p_stat;
  733.   p->p_stat = SWAIT;
  734.   uap.so    = fp->f_so;
  735.   uap.buf   = buf;
  736.   uap.len   = len;
  737.   uap.flags = flags;
  738.   uap.err   = 0;
  739.   IN_recv (p->u_InetBase, &uap);
  740.   if (CURSIG (p))
  741.     SetSignal (0, SIGBREAKF_CTRL_C);
  742.   p->p_stat = ostat;
  743.   if (uap.err == EINTR)
  744.     setrun (FindTask (0));
  745.   
  746.   errno = uap.err;
  747.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  748.   return uap.err ? -1 : uap.rc;
  749. }
  750.  
  751.  
  752. int
  753. recvmsg (int s, caddr_t msg, int flags)
  754. {
  755.   struct a {
  756.           struct socket *so;
  757.           caddr_t msg;
  758.           short   flags;
  759.           short   err;
  760.           int     rc;
  761.   } uap;
  762.   register struct file *fp = getsock (s);
  763.   struct user *p = &u;
  764.   int ostat;
  765.  
  766.   if (! fp)
  767.     return -1;
  768.  
  769.   ostat = p->p_stat;
  770.   p->p_stat = SWAIT;
  771.   uap.so    = fp->f_so;
  772.   uap.msg   = msg;
  773.   uap.flags = flags;
  774.   uap.err   = 0;
  775.   IN_recvmsg (p->u_InetBase, &uap);
  776.   if (CURSIG (p))
  777.     SetSignal (0, SIGBREAKF_CTRL_C);
  778.   p->p_stat = ostat;
  779.   if (uap.err == EINTR)
  780.     setrun (FindTask (0));
  781.   
  782.   errno = uap.err;
  783.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  784.   return uap.err ? -1 : uap.rc;
  785. }
  786.  
  787.  
  788. int
  789. shutdown (int s, int how)
  790. {
  791.   struct a {
  792.           struct socket *so;
  793.           short    how;
  794.           short    err;
  795.   } uap;
  796.   register struct file *fp = getsock (s);
  797.   struct user *p = &u;
  798.   int ostat;
  799.  
  800.   if (! fp)
  801.     return -1;
  802.  
  803.   ostat = p->p_stat;
  804.   p->p_stat = SWAIT;
  805.   uap.so  = fp->f_so;
  806.   uap.how = how;
  807.   uap.err = 0;
  808.   IN_shutdown (p->u_InetBase, &uap);
  809.   if (CURSIG (p))
  810.     SetSignal (0, SIGBREAKF_CTRL_C);
  811.   p->p_stat = ostat;
  812.   if (uap.err == EINTR)
  813.     setrun (FindTask (0));
  814.   
  815.   errno = uap.err;
  816.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  817.   return uap.err ? -1 : 0;
  818. }
  819.  
  820.  
  821. int
  822. setsockopt (int s, int level, int name, caddr_t val, int valsize)
  823. {
  824.   struct a {
  825.           struct socket *so;
  826.           short   level;
  827.           short   name;
  828.           caddr_t val;
  829.           short   valsize;
  830.           short   err;
  831.   } uap;
  832.   register struct file *fp = getsock (s);
  833.   struct user *p = &u;
  834.   int ostat;
  835.  
  836.   if (! fp)
  837.     return -1;
  838.  
  839.   ostat = p->p_stat;
  840.   p->p_stat = SWAIT;
  841.   uap.so      = fp->f_so;
  842.   uap.level   = level;
  843.   uap.name    = name;
  844.   uap.val     = val;
  845.   uap.valsize = valsize;
  846.   uap.err     = 0;
  847.   IN_setsockopt (p->u_InetBase, &uap);
  848.   if (CURSIG (p))
  849.     SetSignal (0, SIGBREAKF_CTRL_C);
  850.   p->p_stat = ostat;
  851.   if (uap.err == EINTR)
  852.     setrun (FindTask (0));
  853.  
  854.   errno = uap.err;
  855.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  856.   return uap.err ? -1 : 0;
  857. }
  858.  
  859.  
  860. int
  861. getsockopt (int s, int level, int name, caddr_t val, int *valsize)
  862. {
  863.   struct a {
  864.           struct socket *so;
  865.           short   level;
  866.           short   name;
  867.           caddr_t val;
  868.           short   valsize;
  869.           short   err;
  870.   } uap;
  871.   register struct file *fp = getsock (s);
  872.   struct user *p = &u;
  873.   int ostat;
  874.  
  875.   if (! fp)
  876.     return -1;
  877.  
  878.   ostat = p->p_stat;
  879.   p->p_stat = SWAIT;
  880.   uap.so      = fp->f_so;
  881.   uap.level   = level;
  882.   uap.name    = name;
  883.   uap.val     = val;
  884.   uap.valsize = valsize ? *valsize : 0;
  885.   uap.err     = 0;
  886.   IN_getsockopt (p->u_InetBase, &uap);
  887.   if (CURSIG (p))
  888.     SetSignal (0, SIGBREAKF_CTRL_C);
  889.   p->p_stat = ostat;
  890.   if (uap.err == EINTR)
  891.     setrun (FindTask (0));
  892.   if (valsize)
  893.     *valsize = uap.valsize;
  894.  
  895.   errno = uap.err;
  896.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  897.   return uap.err ? -1 : 0;
  898. }
  899.  
  900.  
  901. #if 0
  902. /* same problem as with socketpair() */
  903. pipe()
  904. {
  905.         register struct file *rf, *wf;
  906.         struct socket *rso, *wso;
  907.         int r;
  908.  
  909.         u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0);
  910.         if (u.u_error)
  911.                 return;
  912.         u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0);
  913.         if (u.u_error)
  914.                 goto free;
  915.         rf = falloc();
  916.         if (rf == NULL)
  917.                 goto free2;
  918.         r = u.u_r.r_val1;
  919.         rf->f_flag = FREAD;
  920.         rf->f_type = DTYPE_SOCKET;
  921.         rf->f_ops = &socketops;
  922.         rf->f_data = (caddr_t)rso;
  923.         wf = falloc();
  924.         if (wf == NULL)
  925.                 goto free3;
  926.         wf->f_flag = FWRITE;
  927.         wf->f_type = DTYPE_SOCKET;
  928.         wf->f_ops = &socketops;
  929.         wf->f_data = (caddr_t)wso;
  930.         u.u_r.r_val2 = u.u_r.r_val1;
  931.         u.u_r.r_val1 = r;
  932.         if (u.u_error = unp_connect2(wso, rso))
  933.                 goto free4;
  934.         wso->so_state |= SS_CANTRCVMORE;
  935.         rso->so_state |= SS_CANTSENDMORE;
  936.         return;
  937. free4:
  938.         wf->f_count = 0;
  939.         u.u_ofile[u.u_r.r_val2] = 0;
  940. free3:
  941.         rf->f_count = 0;
  942.         u.u_ofile[r] = 0;
  943. free2:
  944.         (void)soo_close(wso);
  945. free:
  946.         (void)soo_close(rso);
  947. }
  948. #endif
  949.  
  950.  
  951. /*
  952.  * Get socket name.
  953.  */
  954. int
  955. getsockname (int fdes, caddr_t asa, int *alen)
  956. {
  957.   struct a {
  958.           struct socket *so;
  959.           caddr_t asa;
  960.           short   alen;
  961.           short   err;
  962.   } uap;
  963.   register struct file *fp = getsock (fdes);
  964.   struct user *p = &u;
  965.   int ostat;
  966.  
  967.   if (! fp)
  968.     return -1;
  969.  
  970.   ostat = p->p_stat;
  971.   p->p_stat = SWAIT;
  972.   uap.so   = fp->f_so;
  973.   uap.asa  = asa;
  974.   uap.alen = alen ? *alen : 0;
  975.   uap.err  = 0;
  976.   IN_getsockname (p->u_InetBase, &uap);
  977.   if (CURSIG (p))
  978.     SetSignal (0, SIGBREAKF_CTRL_C);
  979.   p->p_stat = ostat;
  980.   if (uap.err == EINTR)
  981.     setrun (FindTask (0));
  982.   if (alen)
  983.     *alen = uap.alen;
  984.  
  985.   errno = uap.err;
  986.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  987.   return uap.err ? -1 : 0;
  988. }
  989.  
  990. /*
  991.  * Get name of peer for connected socket.
  992.  */
  993. int
  994. getpeername (int fdes, caddr_t asa, int *alen)
  995. {
  996.   struct a {
  997.           struct socket *so;
  998.           caddr_t asa;
  999.           short   alen;
  1000.           short   err;
  1001.   } uap;
  1002.   register struct file *fp = getsock (fdes);
  1003.   struct user *p = &u;
  1004.   int ostat;
  1005.  
  1006.   if (! fp)
  1007.     return -1;
  1008.  
  1009.   ostat = p->p_stat;
  1010.   p->p_stat = SWAIT;
  1011.   uap.so   = fp->f_so;
  1012.   uap.asa  = asa;
  1013.   uap.alen = alen ? *alen : 0;
  1014.   uap.err  = 0;
  1015.   IN_getpeername (p->u_InetBase, &uap);
  1016.   if (CURSIG (p))
  1017.     SetSignal (0, SIGBREAKF_CTRL_C);
  1018.   p->p_stat = ostat;
  1019.   if (uap.err == EINTR)
  1020.     setrun (FindTask (0));
  1021.   if (alen)
  1022.     *alen = uap.alen;
  1023.  
  1024.   errno = uap.err;
  1025.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1026.   return uap.err ? -1 : 0;
  1027. }
  1028.  
  1029. static struct file *
  1030. getsock (int fdes)
  1031. {
  1032.   register struct file *fp;
  1033.   register struct user *p = &u;
  1034.  
  1035.   if ((unsigned) fdes >= NOFILE)
  1036.     {
  1037.       errno = EBADF;
  1038.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1039.       return 0;
  1040.     }
  1041.  
  1042.   fp = p->u_ofile[fdes];
  1043.   if (fp == NULL)
  1044.     {
  1045.       errno = EBADF;
  1046.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1047.       return (0);
  1048.   }
  1049.   if (fp->f_type != DTYPE_SOCKET && fp->f_type != DTYPE_USOCKET) 
  1050.   {
  1051.       errno = ENOTSOCK;
  1052.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1053.       return (0);
  1054.     }
  1055.   if (fp->f_type == DTYPE_SOCKET && ! p->u_InetBase)
  1056.     {
  1057.       errno = EPIPE; /* ????? */
  1058.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1059.       return 0;
  1060.     }
  1061.   return (fp);
  1062. }
  1063.  
  1064.  
  1065. static int
  1066. soo_read (struct file *fp, char *buf, int len)
  1067. {
  1068.   struct a {
  1069.           struct socket *so;
  1070.           caddr_t buf;
  1071.           int     len;
  1072.           short   flags;
  1073.           short   err;
  1074.           int     rc;
  1075.   } uap;
  1076.   int ostat;
  1077.   struct user *p = &u;
  1078.  
  1079.   ostat = p->p_stat;
  1080.   p->p_stat = SWAIT;
  1081.   uap.so    = fp->f_so;
  1082.   uap.buf   = buf;
  1083.   uap.len   = len;
  1084.   uap.flags = 0;
  1085.   uap.err   = 0;
  1086.   IN_recv (p->u_InetBase, &uap);
  1087.   if (CURSIG (p))
  1088.     SetSignal (0, SIGBREAKF_CTRL_C);
  1089.   p->p_stat = ostat;
  1090.   if (uap.err == EINTR)
  1091.     setrun (FindTask (0));
  1092.   
  1093.   errno = uap.err;
  1094.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1095.   return uap.err ? -1 : uap.rc;
  1096. }
  1097.  
  1098.  
  1099. static int
  1100. soo_write (struct file *fp, char *buf, int len)
  1101. {
  1102.   struct a {
  1103.           struct socket *so;
  1104.           caddr_t buf;
  1105.           int     len;
  1106.           short   flags;
  1107.           short   err;
  1108.           int     rc;
  1109.   } uap;
  1110.   struct user *p = &u;
  1111.   int ostat;
  1112.  
  1113.   ostat = p->p_stat;
  1114.   p->p_stat = SWAIT;
  1115.   uap.so    = fp->f_so;
  1116.   uap.buf   = buf;
  1117.   uap.len   = len;
  1118.   uap.flags = 0;
  1119.   uap.err   = 0;
  1120.   IN_send (p->u_InetBase, &uap);
  1121.   if (CURSIG (p))
  1122.     SetSignal (0, SIGBREAKF_CTRL_C);
  1123.   p->p_stat = ostat;
  1124.   if (uap.err == EINTR)
  1125.     setrun (FindTask (0));
  1126.   
  1127.   errno = uap.err;
  1128.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1129.   return uap.err ? -1 : uap.rc;
  1130. }
  1131.  
  1132.  
  1133.  
  1134. static int
  1135. soo_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
  1136. {
  1137.   struct a {
  1138.           struct socket *so;
  1139.           short      cmd;
  1140.           caddr_t data;
  1141.           short   err;
  1142.   } uap;
  1143.   struct user *p = &u;
  1144.   int ostat;
  1145.  
  1146.   /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  1147.      code they used, but for whatever reason they decided they needed their
  1148.      own kind of ioctl encoding :-((
  1149.      
  1150.      Well then, here we go, and map `normal' cmds into CBM cmds: */
  1151.  
  1152.   switch (cmd)
  1153.    {
  1154.    case    SIOCADDRT    : cmd = ('r'<<8)|1; break;
  1155.    case    SIOCDELRT    : cmd = ('r'<<8)|2; break;
  1156.    case    SIOCSIFADDR    : cmd = ('i'<<8)|3; break;
  1157.    case    SIOCGIFADDR    : cmd = ('i'<<8)|4; break;
  1158.    case    SIOCSIFDSTADDR    : cmd = ('i'<<8)|5; break;
  1159.    case    SIOCGIFDSTADDR    : cmd = ('i'<<8)|6; break;
  1160.    case    SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  1161.    case    SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  1162.    case    SIOCGIFCONF    : cmd = ('i'<<8)|9; break;
  1163.    case    SIOCSIFMTU    : cmd = ('i'<<8)|10; break;
  1164.    case    SIOCGIFMTU    : cmd = ('i'<<8)|11; break;
  1165.    case    SIOCGIFBRDADDR    : cmd = ('i'<<8)|12; break;
  1166.    case    SIOCSIFBRDADDR    : cmd = ('i'<<8)|13; break;
  1167.    case    SIOCGIFNETMASK    : cmd = ('i'<<8)|14; break;
  1168.    case    SIOCSIFNETMASK    : cmd = ('i'<<8)|15; break;
  1169.    case    SIOCGIFMETRIC    : cmd = ('i'<<8)|16; break;
  1170.    case    SIOCSIFMETRIC    : cmd = ('i'<<8)|17; break;
  1171.    case SIOCSARP    : cmd = ('i'<<8)|18; break;
  1172.    case SIOCGARP    : cmd = ('i'<<8)|19; break;
  1173.    case SIOCDARP    : cmd = ('i'<<8)|20; break;
  1174.    case SIOCATMARK    : cmd = ('i'<<8)|21; break;
  1175.    case FIONBIO        : cmd = ('m'<<8)|22; break;
  1176.    case FIONREAD    : cmd = ('m'<<8)|23; break;
  1177.    case FIOASYNC    : cmd = ('m'<<8)|24; break;
  1178.    case SIOCSPGRP    : cmd = ('m'<<8)|25; break;
  1179.    case SIOCGPGRP    : cmd = ('m'<<8)|26; break;
  1180.    
  1181.    default:
  1182.      /* we really don't have to bother the library with cmds we can't even
  1183.         map over... */
  1184.      errno = EINVAL;
  1185.      KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1186.      return -1;
  1187.    }
  1188.  
  1189.   ostat = p->p_stat;
  1190.   p->p_stat = SWAIT;
  1191.   uap.so    = fp->f_so;
  1192.   uap.cmd   = cmd;
  1193.   uap.data  = data;
  1194.   uap.err   = 0;
  1195.   IN_ioctl (p->u_InetBase, &uap);
  1196.   if (CURSIG (p))
  1197.     SetSignal (0, SIGBREAKF_CTRL_C);
  1198.   p->p_stat = ostat;
  1199.   if (uap.err == EINTR)
  1200.     setrun (FindTask (0));
  1201.   
  1202.   errno = uap.err;
  1203.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1204.   return uap.err ? -1 : 0;
  1205. }
  1206.  
  1207.  
  1208. static int
  1209. soo_select (struct file *fp, int select_cmd, int io_mode)
  1210. {
  1211.   struct a {
  1212.           struct socket **sotable;  /* just one socket used */
  1213.       int      *inp;
  1214.       int      *out;
  1215.       int      *exc;
  1216.       void    *process;
  1217.       short      exec_sig;
  1218.       short      numfd;
  1219.       short   err;
  1220.       short   rc;
  1221.   } uap;
  1222.   int ostat;
  1223.   struct user *p = &u;
  1224.   int in, out, exc;
  1225.  
  1226.   switch (io_mode)
  1227.     {
  1228.     case SELMODE_IN:
  1229.       in = 1; out = 0; exc = 0;
  1230.       break;
  1231.     
  1232.     case SELMODE_OUT:
  1233.       in = 0; out = 1; exc = 0;
  1234.       break;
  1235.  
  1236.     case SELMODE_EXC:
  1237.       in = 0; out = 0; exc = 1;
  1238.       break;
  1239.     }
  1240.  
  1241.   ostat = p->p_stat;
  1242.   p->p_stat = SWAIT;
  1243.   uap.sotable = & fp->f_so;
  1244.   uap.inp = ∈
  1245.   uap.out = &out;
  1246.   uap.exc = &exc;
  1247. #if 0
  1248.   uap.process = FindTask (0);
  1249.   uap.exec_sig = p->u_sigio;
  1250. #else
  1251.   /* sigh, above doesn't work.. */
  1252.   uap.process = 0;
  1253.   uap.exec_sig = 0;
  1254. #endif
  1255.   uap.numfd = 1;
  1256.   uap.err = 0;
  1257.   IN_select (p->u_InetBase, &uap);
  1258.   if (CURSIG (p))
  1259.     SetSignal (0, SIGBREAKF_CTRL_C);
  1260.   p->p_stat = ostat;
  1261.       
  1262.   errno = uap.err;
  1263.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1264.   if (select_cmd == SELCMD_PREPARE)
  1265. #if 0
  1266.     return 1 << p->u_sigio;
  1267. #else
  1268.     return 0;
  1269. #endif
  1270.   else
  1271.     return uap.rc == 1 ? 1 : 0;
  1272. }
  1273.  
  1274.  
  1275. static int
  1276. soo_close (struct file *fp)
  1277. {
  1278.   struct a {
  1279.           struct socket *so;
  1280.       short   err;
  1281.   } uap;
  1282.   struct user *p = &u;
  1283.   int err = 0;
  1284.  
  1285.   ix_lock_base ();
  1286.   fp->f_count--;
  1287.   if (fp->f_count == 0)
  1288.     {
  1289.       /* don't have the base locked for IN_close, this MAY block!! */
  1290.       uap.so = fp->f_so;
  1291.       ix_unlock_base ();
  1292.       IN_close (p->u_InetBase, &uap);
  1293.       err = uap.err;
  1294.     }
  1295.   else
  1296.     ix_unlock_base ();
  1297.  
  1298.   errno = err;
  1299.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  1300.   return err ? -1 : 0;
  1301. }
  1302.